home *** CD-ROM | disk | FTP | other *** search
- /*****
- from CTRACE: A MESSAGE LOGGING CLASS
- by William D. Cramer in Dr. Dobbs Journal #170, p. 44-55, 116-120.
- *****/
-
- /** CLogPanorama.c -- Methods for a CLogPanorama class object. **/
- #include "CLogPanorama.h" /* defines log class */
-
- /** ILogPanorama -- Initializes an instance of the log panorama class. **/
- void CLogPanorama::ILogPane
- (
- short records, /* number of records in LogList */
- CBureaucrat *aSupervisor, /* in-charge for this panorama */
- CWindow *aWindow /* window object to place pane into */
- )
- {
- FontInfo
- fontParms; /* paramaters of selected font */
- short
- lineSpace, /* pixels per line */
- charSpace; /* pixels per widest character */
- Rect
- maxWindowRect, /* maximum growth of log window */
- marginRect; /* inside margins of viewable area */
- CScrollPane
- *theScrollPane; /* pane associated with panorama */
-
- /* Set drawing parameters and adjust record size, if necessary. **/
- aWindow->Prepare ();
- TextFont (LOGPANE_FONT);
- TextSize (LOGPANE_FONT_SIZE);
- GetFontInfo (&fontParms);
- lineSpace = fontParms.ascent+fontParms.descent+fontParms.leading;
- charSpace = fontParms.widMax;
- if ( ((long)records*(long)lineSpace) > (long)INT_MAX)
- records = INT_MAX / lineSpace;
- SetRect (&maxWindowRect, MIN_WSIZE, MIN_WSIZE,
- (MAX_LOGREC_CHAR * charSpace) + SBARSIZE,
- (records * lineSpace) + SBARSIZE);
- aWindow->SetSizeRect (&maxWindowRect);
-
- /* Initialize Panorama's ScrollPane, set scroll units to the defaulted
- ** values, and attach the Panorama to the ScrollPane. */
- theScrollPane = new (CScrollPane);
- theScrollPane->IScrollPane(aWindow, this, 0, 0, 0, 0,sizELASTIC, sizELASTIC,TRUE, TRUE, TRUE);
- theScrollPane->FitToEnclFrame (TRUE, TRUE);
- theScrollPane->SetSteps (LOGPANE_HORZ_SCROLL, LOGPANE_VERT_SCROLL);
-
- /* Initialize Panarama to include maximum chars wide and maximum records tall,
- ** set the Panarama units to one char wide and one char tall. */
- CPanorama::IPanorama(theScrollPane, aSupervisor, MAX_LOGREC_CHAR,
- records, 0, 0, sizELASTIC, sizELASTIC);
- SetScales (charSpace, lineSpace);
- FitToEnclosure (TRUE, TRUE);
- theScrollPane->InstallPanorama (this);
-
- /* Create the LogList and initialize. */
- itsLogList = new (CLogList);
- itsLogList->ILogList (records);
- }
-
- /** Draw() -- Refreshes the visible portion of the window. **/
- void CLogPanorama::Draw
- (
- Rect *drawRect /* portion of window to refresh */
- )
- {
- short
- firstRec, /* record number of first visible line */
- hScale, /* how many pixels wide is a character? */
- lastRec, /* record number of last line */
- totalRec, /* total number of records in LogList */
- vScale; /* how many pixels tall is a line? */
- register short
- currRow, /* window coordinates of current row */
- rec; /* loop counter */
- char
- buff[MAX_LOGREC_CHAR]; /* buffer for fetching log records */
- /* First, translate draw rectangle to records. **/
- GetScales (&hScale, &vScale);
- totalRec = (short)itsLogList->GetNumItems ();
- firstRec = (drawRect->top / vScale);
- if (firstRec == 0)
- firstRec = 1;
- lastRec = (drawRect->bottom / vScale) + 1;
- if (lastRec > totalRec)
- lastRec = totalRec;
- /* Refresh all of visible lines. **/
- Prepare ();
- for (rec=firstRec, currRow=firstRec*vScale;
- rec<=lastRec;
- rec++, currRow+=vScale)
- {
- itsLogList->GetString (rec, buff);
- MoveTo (LOGPANE_INSET, currRow);
- DrawString (CtoPstr(buff));
- }
- }
-
- /** AddString() -- Adds a new string to panorama. **/
- void CLogPanorama::AddString
- (
- char *theString /* null-terminated string to add */
- )
- {
- Rect
- frameRect; /* interior of current frame */
- short
- listLimits, /* maximum the LogList will hold */
- hSpan, /* the horizontal span of frame */
- vSpan, /* the vertical span of frame */
- hScale, /* horizontal pixels in panarama unit */
- vScale; /* vertical pixels in panarama unit */
- Point
- topRecord, /* LogList record number of top row */
- bottomRecord, /* LogList record number of bottom row */
- newRecord, /* LogList record number of new row */
- currPosition, /* panorama coordinates of top/left frame */
- recPosition; /* panorama coordinates of new string */
- /* Add the record to the LogList. */
- itsLogList->AddString (theString);
- /* Get coordinates of current frame and calculate tentative coordinates for
- newly added record. */
- GetPosition (&currPosition);
- GetFrameSpan (&hSpan, &vSpan);
- GetScales (&hScale, &vScale);
- topRecord.v = currPosition.v + 1;
- bottomRecord.v = topRecord.v + vSpan - 1;
- newRecord.v = (short)itsLogList->GetNumItems ();
- newRecord.h = currPosition.h;
-
- /* Determine where we are in reference to bottom of screen and of list. **/
- if (newRecord.v > (bottomRecord.v+1) )
- {
- /* bottom record isn't visible */
- currPosition.v = newRecord.v - vSpan;
- ScrollTo (currPosition, FALSE);
- GetInterior (&frameRect);
- Prepare ();
- EraseRect (&frameRect);
- }
- else
- {
- /* bottom record is visible */
- listLimits = itsLogList->GetMaxRecordCount ();
- if (bottomRecord.v < listLimits)
- {
- /* room in list--create blank line if necessary */
- if (newRecord.v == (bottomRecord.v + 1) )
- {
- Scroll (0, 1, TRUE);
- SetRect (&frameRect, newRecord.h*hScale, (newRecord.v-1)*vScale,(newRecord.h+hSpan)*hScale, (newRecord.v)*vScale);
- }
- else
- SetRect (&frameRect, newRecord.h*hScale, (newRecord.v-1)*vScale,
- (newRecord.h+hSpan-1)*hScale, (newRecord.v)*vScale);
- }
- else if (bottomRecord.v > listLimits)
- {
- currPosition.v = newRecord.v - vSpan;
- ScrollTo (currPosition, FALSE);
- GetInterior (&frameRect);
- Prepare ();
- EraseRect (&frameRect);
- }
- else
- {
- /* bottom of pane=limit of list, so do our own scrolling */
- Prepare ();
- GetInterior (&frameRect);
- ScrollRect (&frameRect, 0, -vScale, gUtilRgn);
- SetRect (&frameRect, bottomRecord.h*hScale, (bottomRecord.v-1)*vScale,(bottomRecord.h+hSpan-1)*hScale, (bottomRecord.v)*vScale);
- EraseRect (&frameRect);
- }
- }
- Draw (&frameRect);
- itsScrollPane->Calibrate();
- }
-